package com.czl.myRabbitMq.commom;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.io.*;

/**
 * 这个包里的对象为服务端和客户端都能使用的对象
 */
//将一个对象进行序列化和反序列化 java中的对象都可以通过一下逻辑进行序列化 但前提是实现接口 Serializable

@Slf4j
public class BinaryTransformTool {

    /**
     * 这样写是设置版本号的意思
     * 就是比如我今天定义了一个Message对象 对其进行了序列化 并存入了文件中
     * 要是第二天有人对Message对象进行修改 然后我如果读取该序列化数据 很大概率
     * 是会报错的 为了防止上述情况发生 这里定义一个版本表示 表示如果我今天定义版本一
     * 然后将数据序列化写入文件的时候 这个1这个数据就被保存下来了 要是有人对Message对象
     * 进行了修改 就手动加一 这样反序列化的时候就能防止读取旧版本数据了
     *
     * 这个属性一般加在进行序列化的对象中 而不是这里!!!!!!!!!!!!!!!!
     */
    private static final long serialVersionUID = 1L;
    //将对象进行序列化操作
    @SneakyThrows
    public static byte[] getBinaryData(Object data){
        //因为我们不知道将对象转为二进制数据后 这个数据的长度是几个字节  所以我们使用
        //ByteArrayOutputStream 这个对象 这个对象本质是一个可变长的 字节数组
        try(ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
            //java标准库中提供了将对象序列化的类 就是 ObjectOutputStream 后面构造器中传入的参数就是
            //序列化时将数据写入的地方 这里传入的是byteArrayOutputStream 所以写入这个对象里面
            //要是传入的是文件 则写入文件里面
            try (ObjectOutputStream outputStream = new ObjectOutputStream(byteArrayOutputStream)) {
                outputStream.writeObject(data);
            }
            return byteArrayOutputStream.toByteArray();
        }
    }
    //将二进制数据转化为对象
    @SneakyThrows
    public static Object fromData(byte[] data){
        Object object = null;
          try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(data)){
              try(ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream)){
                   object = objectInputStream.readObject();
              }
              return object;
          }
    }
}
